package com.example.nick.bodyapplication.log

import android.text.TextUtils
import android.util.Log

public class KtLog {
    companion object {
        const val NULL_TIPS = "Log with null object"
        private const val DEFAULT_MESSAGE = "execute"
        private const val PARAM = "Param"
        private const val NULL = "null"
        private const val TAG_DEFAULT = "KLog"
        private const val SUFFIX = ".java"
        private val mGlobalTag: String? = null
        private const val mIsGlobalTagEmpty = true
        private const val IS_SHOW_LOG = true

        fun i(tag: String, msg: String) {
            val contents = wrapperContent(4, tag, msg)
            val iTag = contents?.get(0)
            val iMsg = contents?.get(1)
            val iHeadString = contents?.get(2)
            Log.i(iTag, iMsg + iHeadString)
        }

        private fun wrapperContent(
            stackTraceIndex: Int,
            tagStr: String?,
            vararg objects: Any
        ): Array<String?>? {
            val stackTrace = Thread.currentThread().stackTrace
            val targetElement = stackTrace[stackTraceIndex]
            var className = targetElement.className
            val classNameInfo = className.split(".").toTypedArray()
            if (classNameInfo.isNotEmpty()) {
                className = classNameInfo[classNameInfo.size - 1] + SUFFIX
            }
            if (className.contains("$")) {
                className = className.split("$").toTypedArray()[0] + SUFFIX
            }
            val methodName = targetElement.methodName
            var lineNumber = targetElement.lineNumber
            if (lineNumber < 0) {
                lineNumber = 0
            }
            var tag = tagStr ?: className
            if (mIsGlobalTagEmpty && TextUtils.isEmpty(tag)) {
                tag = TAG_DEFAULT
            } else if (!mIsGlobalTagEmpty) {
                tag = mGlobalTag
            }
            val msg = if (objects == null) NULL_TIPS else getObjectsString(*objects)!!
            val headString = "[ ($className:$lineNumber)#$methodName ] "
            Log.e("log", "$className/$lineNumber/$methodName")
            return arrayOf(tag, msg, headString)
        }

        private fun getObjectsString(vararg objects: Any): String? {
            return if (objects.size > 1) {
                val stringBuilder = StringBuilder()
                stringBuilder.append("\n")
                for (i in objects.indices) {
                    val `object` = objects[i]
                    if (`object` == null) {
                        stringBuilder.append(PARAM).append("[").append(i).append("]")
                            .append(" = ").append(NULL).append("\n")
                    } else {
                        stringBuilder.append(PARAM).append("[").append(i).append("]")
                            .append(" = ").append(`object`.toString()).append("\n")
                    }
                }
                stringBuilder.toString()
            } else if (objects.size == 1) {
                val `object` = objects[0]
                `object`?.toString() ?: NULL
            } else {
                NULL
            }
        }
    }
}